矩阵(Matrix)是金融数学的核心工具,广泛应用于:
理解矩阵运算是掌握现代投资组合理论(MPT)和CAPM的基础。
单位矩阵:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
零矩阵:
[[0. 0. 0.]
[0. 0. 0.]]
全1矩阵:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]]
在金融中,对角矩阵可用于表示各资产的独立波动率。
| 特性 | np.matrix(已弃用) |
np.ndarray(推荐) |
|---|---|---|
* 运算符 |
矩阵乘法 | 元素乘法 |
| 维度 | 始终2维 | 可以任意维 |
| 状态 | 已弃用(1.20+) | 推荐使用 |
最佳实践:始终使用 np.ndarray 表示矩阵,使用 @ 运算符进行矩阵乘法。
两个向量 \(\mathbf{a}\) 和 \(\mathbf{b}\) 的点积为:
\[ \large{\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1b_1 + a_2b_2 + \cdots + a_nb_n} \]
金融含义:点积用于计算加权平均,如投资组合收益率:
\[ \large{R_p = \sum_{i=1}^{n} w_i R_i = \mathbf{w} \cdot \mathbf{R}} \]
其中 \(\mathbf{w}\) 是权重向量,\(\mathbf{R}\) 是收益率向量。
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import numpy as np # 导入NumPy数值计算库
#使用列表定义5月26日收益率数据 return_0526、权重数据 weight。
return_0526=[0.0172,0.0243,-0.0029,0.0021]
weight=[0.15,0.20,0.25,0.4] # 定义列表weight
#计算投资组合日收益率
return_daily=np.dot(return_0526,weight).round(3)
print(f'投资组合5月26日收益率为:{return_daily}') # 输出投资组合5月26日收益率为投资组合5月26日收益率为:0.008
矩阵 \(\mathbf{A}\)(\(m \times n\))与 \(\mathbf{B}\)(\(n \times p\))的乘积 \(\mathbf{C}\)(\(m \times p\)):
\[ \large{c_{ij} = \sum_{k=1}^{n} a_{ik} b_{kj}} \]
重要性质:
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]]) # 2×3矩阵
B = np.array([[7, 8], [9, 10], [11, 12]]) # 3×2矩阵
# 方法1: @运算符(推荐,Python 3.5+)
C1 = A @ B
print('方法1 - @运算符:')
print(C1)
# 方法2: np.matmul()函数
C2 = np.matmul(A, B)
print('\n方法2 - matmul函数:')
print(C2)
# 方法3: np.dot()函数
C3 = np.dot(A, B)
print('\n方法3 - dot函数:')
print(C3)
print(f'\n结果一致: {np.array_equal(C1, C2) and np.array_equal(C2, C3)}')方法1 - @运算符:
[[ 58 64]
[139 154]]
方法2 - matmul函数:
[[ 58 64]
[139 154]]
方法3 - dot函数:
[[ 58 64]
[139 154]]
结果一致: True
import numpy as np
# 3只股票在4个交易日的收益率矩阵(每行一只股票,每列一个交易日)
returns = np.array([
[0.01, 0.02, -0.01, 0.03], # 股票A
[0.02, 0.01, 0.03, -0.01], # 股票B
[-0.01, 0.03, 0.02, 0.04] # 股票C
])
# 投资组合权重:A 30%、B 50%、C 20%
weights = np.array([0.3, 0.5, 0.2])
# 矩阵乘法:权重(1×3) × 收益率(3×4) = 组合收益(1×4)
portfolio_returns = weights @ returns
print(f'投资组合每日收益率: {portfolio_returns}')
# 累计收益率
cumulative_return = np.prod(1 + portfolio_returns) - 1
print(f'期间累计收益率: {cumulative_return:.4%}')投资组合每日收益率: [0.011 0.017 0.016 0.012]
期间累计收益率: 5.7174%
对于随机向量 \(\mathbf{X}\),协方差矩阵 \(\mathbf{\Sigma}\) 的元素为:
\[ \large{\Sigma_{ij} = \text{Cov}(X_i, X_j) = E[(X_i - \mu_i)(X_j - \mu_j)]} \]
三大性质:
协方差矩阵:
[[ 2.72117409e-04 -1.57105634e-05 -4.43202407e-05]
[-1.57105634e-05 3.83454758e-04 -5.39437601e-05]
[-4.43202407e-05 -5.39437601e-05 4.95427395e-04]]
相关系数矩阵:
[[ 1. -0.04863585 -0.12070741]
[-0.04863585 1. -0.12376394]
[-0.12070741 -0.12376394 1. ]]
\[ \large{\text{Corr}(X, Y) = \frac{\text{Cov}(X, Y)}{\sigma_X \cdot \sigma_Y}} \]
import numpy as np
np.random.seed(42)
returns = np.random.randn(100, 3) * 0.02
cov_matrix = np.cov(returns, rowvar=False)
corr_matrix = np.corrcoef(returns, rowvar=False)
# 标准差向量
std_devs = np.sqrt(np.diag(cov_matrix))
# 外积构造分母矩阵
corr_from_cov = cov_matrix / np.outer(std_devs, std_devs)
print('从协方差计算的相关系数矩阵:')
print(corr_from_cov)
print(f'\n两种方法一致: {np.allclose(corr_matrix, corr_from_cov)}')从协方差计算的相关系数矩阵:
[[ 1. -0.04863585 -0.12070741]
[-0.04863585 1. -0.12376394]
[-0.12070741 -0.12376394 1. ]]
两种方法一致: True
\[ \large{\sigma_p^2 = \mathbf{w}^T \mathbf{\Sigma} \mathbf{w} = \sum_{i=1}^{n}\sum_{j=1}^{n} w_i w_j \sigma_{ij}} \]
import numpy as np
# 3只股票的协方差矩阵
cov_matrix = np.array([
[0.0100, 0.0018, 0.0011],
[0.0018, 0.0081, 0.0009],
[0.0011, 0.0009, 0.0064]
])
weights = np.array([0.3, 0.5, 0.2]) # A 30%, B 50%, C 20%
# 矩阵运算:wΣw'
portfolio_var = weights @ cov_matrix @ weights.T
portfolio_std = np.sqrt(portfolio_var)
print(f'投资组合方差: {portfolio_var:.6f}')
print(f'投资组合标准差(波动率): {portfolio_std:.4%}')投资组合方差: 0.004033
投资组合标准差(波动率): 6.3506%
import numpy as np
cov_matrix = np.array([
[0.0100, 0.0018, 0.0011],
[0.0018, 0.0081, 0.0009],
[0.0011, 0.0009, 0.0064]
])
weights = np.array([0.3, 0.5, 0.2])
portfolio_std = np.sqrt(weights @ cov_matrix @ weights.T)
individual_stds = np.sqrt(np.diag(cov_matrix))
weighted_avg_std = np.sum(weights * individual_stds)
print(f'加权平均标准差: {weighted_avg_std:.4%}')
print(f'组合标准差: {portfolio_std:.4%}')
print(f'风险降低: {(weighted_avg_std - portfolio_std) / weighted_avg_std:.2%}')
# 体现了"不要把鸡蛋放在同一个篮子里"的原理加权平均标准差: 9.1000%
组合标准差: 6.3506%
风险降低: 30.21%
金融中许多问题可转化为线性方程组:
import numpy as np
# 因子载荷矩阵:3只资产对3个因子的敏感度
A = np.array([
[1.2, 0.8, 0.5], # 资产1
[0.9, 1.1, 0.3], # 资产2
[0.7, 0.6, 0.9] # 资产3
])
b = np.array([0.08, 0.06, 0.07]) # 资产超额收益率
# 求解因子收益:Ax = b
factor_returns = np.linalg.solve(A, b)
print('因子收益率:')
print(f' 因子1: {factor_returns[0]:.4%}')
print(f' 因子2: {factor_returns[1]:.4%}')
print(f' 因子3: {factor_returns[2]:.4%}')
# 验证
b_reconstructed = A @ factor_returns
print(f'\n验证通过: {np.allclose(b, b_reconstructed)}')因子收益率:
因子1: 4.7480%
因子2: 0.5570%
因子3: 3.7135%
验证通过: True
矩阵可逆的充要条件:
逆矩阵性质:\(\mathbf{A} \times \mathbf{A}^{-1} = \mathbf{I}\)
import numpy as np
A = np.array([[4, 7], [2, 6]])
print('矩阵A:')
print(A)
# 行列式
det_A = np.linalg.det(A)
print(f'\n行列式: {det_A:.4f}')
# 秩
rank_A = np.linalg.matrix_rank(A)
print(f'秩: {rank_A}')
# 逆矩阵
A_inv = np.linalg.inv(A)
print('\n逆矩阵 A^(-1):')
print(A_inv)
# 验证 A × A^(-1) = I
identity = A @ A_inv
print(f'\n是否为单位矩阵: {np.allclose(identity, np.eye(2))}')矩阵A:
[[4 7]
[2 6]]
行列式: 10.0000
秩: 2
逆矩阵 A^(-1):
[[ 0.6 -0.7]
[-0.2 0.4]]
是否为单位矩阵: True
数值稳定性提示:接近奇异的矩阵(行列式接近0)会导致数值不稳定。在金融中,协方差矩阵接近奇异意味着存在高度相关的资产。
对于方阵 \(\mathbf{A}\),若存在非零向量 \(\mathbf{v}\) 和标量 \(\lambda\) 使得:
\[ \large{\mathbf{Av} = \lambda\mathbf{v}} \]
则 \(\lambda\) 为特征值,\(\mathbf{v}\) 为特征向量。
金融应用:
import numpy as np
cov_matrix = np.array([
[0.0100, 0.0018, 0.0011],
[0.0018, 0.0081, 0.0009],
[0.0011, 0.0009, 0.0064]
])
# eigh:对称矩阵的特征值分解(特征值升序排列)
eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)
print('特征值:')
for i, val in enumerate(eigenvalues):
print(f' λ{i+1} = {val:.6f}')
# 解释方差比例
explained_var_ratio = eigenvalues / eigenvalues.sum()
print(f'\n解释方差比例:')
for i, ratio in enumerate(explained_var_ratio):
print(f' PC{i+1}: {ratio:.2%}')
# 累计解释方差
cumulative_var = np.cumsum(explained_var_ratio)
print(f'\n累计解释方差:')
for i, cum_var in enumerate(cumulative_var):
print(f' 前{i+1}个主成分: {cum_var:.2%}')特征值:
λ1 = 0.005973
λ2 = 0.007051
λ3 = 0.011476
解释方差比例:
PC1: 24.38%
PC2: 28.78%
PC3: 46.84%
累计解释方差:
前1个主成分: 24.38%
前2个主成分: 53.16%
前3个主成分: 100.00%
对于非方阵或奇异矩阵,使用 Moore-Penrose 伪逆 求最小二乘解。
import numpy as np
# 超定系统:4个方程,2个未知数
A = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
b = np.array([1, 2, 3, 4])
# Moore-Penrose伪逆
A_pinv = np.linalg.pinv(A)
# 最小二乘解:最小化 ||Ax - b||²
x = A_pinv @ b
print(f'最小二乘解: {x}')
# 残差与均方误差
residual = b - (A @ x)
mse = np.mean(residual ** 2)
print(f'均方误差: {mse:.6f}')最小二乘解: [-4.4408921e-16 5.0000000e-01]
均方误差: 0.000000
| 操作 | 函数/运算符 | 用途 |
|---|---|---|
| 矩阵乘法 | @ / np.matmul() |
投资组合计算 |
| 协方差矩阵 | np.cov() |
风险度量 |
| 线性方程组 | np.linalg.solve() |
因子收益求解 |
| 逆矩阵 | np.linalg.inv() |
方程组求解 |
| 特征值分解 | np.linalg.eigh() |
PCA降维 |
| 伪逆 | np.linalg.pinv() |
最小二乘回归 |
[商业大数据分析与应用]